
#ifndef __BROKER_4_H
#define __BROKER_4_H

#include "../net/EncMessage.h"
#include "../db/KeyDB.h"
#include "../db/DBArbitrator.h"
#include "../aprtools/APRBucketBrigade.h"
#include "../aprtools/APRMutex.h"
#include "../net/BrokerMessage.h"
#include "../net/SSHChain.h"
#include "../xml/DOMDocument.h"
#include "netgeneral.h"

#define MAX_TABLE_ENTS 20
#define MAX_HEADER_LENGTH 8192

class Broker4
{
   public:
      static std::vector<char> *SimpleCryptDataChunk(const char *cname, const char *sname, KeyPair *rsa, KeyPair *signing, const char *datachunk, int length, int dodecrypt, int docompress, apr_pool_t *mp, int *trusted);
      static APRBucketBrigade *CryptDataChunkToBucket(const char *cname, const char *sname, KeyPair *rsa, KeyPair *signing, const char *datachunk, int length, int dodecrypt, int docompress, apr_pool_t *mp, int *trusted);
      static std::vector<char> *ReadIntoBuffer(APRBucketBrigade *aprbb, int len, APRMutex *waiting_block);
      static apr_size_t GetContentLength(const apr_table_t *htable);
      static apr_table_t *GetTable(char *buffer, apr_size_t clength, const char *separator, const char *eol, apr_pool_t *mp);
      static apr_table_t *GetTable(APRBucketBrigade *aprbb, apr_size_t clength, const char *separator, const char *eol, apr_pool_t *mp, APRMutex *waiting_block);
      static int WriteEncryptedMessageToBucket(APRBucketBrigade *aprbb, EncMessage *msg, KeyDB *kdb);
      static int WriteEncMessageToBB(APRBucketBrigade *aprbb, EncMessage *msg, KeyDB *kdb);
      static int ReadEncMessageFromBB(APRBucketBrigade *aprbb, EncMessage *msg, KeyDB *kdb, APRMutex *waiting_block);
      /*
      static void AcceptUserRegistration(AllDBs *dbs, const char *temp_username);
      static void DenyUserRegistration(AllDBs *dbs, const char *temp_username);
      static void CleanUpUserRegistration(AllDBs *dbs, const char *temp_username);
      */
      static SSHChain *GetClusterConnection(AllDBs *dbs, KeyDB *sshkeydb, const char *final_user, const char *sshkeychainpass, const char *clustertoken, apr_pool_t *mp);
      static char *GetClusterListForWorkStore(AllDBs *dbs, KeyDB *sshkeydb, const char *store_id, const char *clusterlist, const char *sshkeychainpass, int *success, apr_pool_t *mp);
      static int TryToStartWorkStore(AllDBs *dbs, const char *store_id, int instances, int maxtimesecs, const char *sshkeychainpass, const char *clusterlist, apr_pool_t *mp);
      static void TryToStartUnresourcedWork(AllDBs *dbs, const char *exthost, int extport, apr_pool_t *mp);

      static void UserRegistration(AllDBs *dbs, const char *clientname, BrokerMessage *sentmsg, BrokerMessage *replymsg);
      static int ProcessUploadedXMLDescriptor(AllDBs *dbs, const char *uuid, BrokerMessage *sentmsg, apr_off_t *sizeused);
      static void CheckFileComplete(const char *sessionid, int blockno, BrokerMessage *replymsg);
      static void WriteFileAndCheckHash(AllDBs *dbs, int blockno, BrokerMessage *sentmsg, BrokerMessage *replymsg);
      static int ProcessXMLDescriptorFromUploadRequest(const char *uuid, const char *username, AllDBs *dbs, const char *buffer, int len, int *errmsg, apr_pool_t *mp, const char *workdataname);
      static void WriteFakeFile(const char *filename, apr_size_t length, int *errmsg, int *mustcancel, apr_pool_t *mp);
      static apr_size_t GetFileSize(const char *filename, apr_pool_t *mp);
      static std::vector<char> *EncryptDataChunk(const char *cname, const char *sname, KeyPair *rsa, KeyPair *signing, const char *datachunk, int length, int dodecrypt, int docompress, apr_pool_t *mp, int *trusted);
      static std::vector<char> *EncryptFileBlock(const char *cname, const char *sname, KeyPair *rsa, KeyPair *signing, const char *filename, apr_size_t rangebegin, apr_size_t rangeend, int dodecrypt, int docompress, apr_pool_t *mp, int *trusted);
};

#endif
